package com.nassir.aop;

import java.lang.reflect.Method;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

/**
 * AOP
 * @author nassir wen
 */
@Aspect
@Component
public class Aop
{
    private final static Log logger = LogFactory.getLog(Aop.class);
    
    /**
     * 定义一个切入点,在方法含@Anno注解位置切入
     */
    @Pointcut("@annotation(com.nassir.aop.Anno)")
    public void aopPoint()
    {
    }

    /**
     * @param jp
     * @return
     */
    @Around("aopPoint()")
    public Object execAop(ProceedingJoinPoint jp) throws Throwable
    {
        long start = System.currentTimeMillis();
        
        Method method = getMethod(jp);
        Anno anno = method.getAnnotation(Anno.class);
        
        String methodName = method.getName();
        
        String aop = anno.isAop();
        
        Object retVal = null;
        if (logger.isInfoEnabled()) {
            logger.info("begin exec fun ######: " +  methodName);
        }
        if (StringUtils.equalsIgnoreCase(aop,"Y"))
        {
            retVal = jp.proceed();
        }else {
            //如果注解aop不为"Y/y"返回err
            retVal = "err";
        }
        if (logger.isInfoEnabled()) {
            logger.info("end exec fun ######: " +  methodName);
        }
        
        if (logger.isInfoEnabled()) {
            logger.info("spend time : " + (System.currentTimeMillis()-start) + "ms");
        }
        return retVal;
    }

    private Method getMethod(JoinPoint jp) throws NoSuchMethodException
    {
        Signature sig = jp.getSignature();
        MethodSignature msig = (MethodSignature) sig;
        return getClass(jp).getMethod(msig.getName(),
                msig.getParameterTypes());
    }
    
    private Class<? extends Object> getClass(JoinPoint jp) throws NoSuchMethodException{
        return jp.getTarget().getClass();
    }
}
